package cn.modfun.web.core.config;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.modfun.web.core.kit.StrKit;
import org.apache.log4j.Logger;
import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;

import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.template.Engine;

import cn.hutool.core.util.StrUtil;
import cn.hutool.setting.Setting;
import cn.modfun.web.core.annotation.Controller;
import cn.modfun.web.core.annotation.Model;
import cn.modfun.web.core.hanlder.ParameterFilterHandler;
import cn.modfun.web.core.interceptor.ParameterValidatorInterceptor;

/**
 * 默认jfinal框架配置项
 * @author LinCH
 *
 */
public class DefaultConfig extends JFinalConfig {
	
	private static Logger logger = Logger.getLogger(DefaultConfig.class);
	
	public static Setting config = new Setting("config/jfinal.txt");
	
	
	/**
	 * 配置常量
	 */
	@Override
	public void configConstant(Constants me) {
		// TODO Auto-generated method stub
		me.setDevMode(config.getBool("dev_mode", "common", false));
	}

	/**
	 * 配置路由
	 * <p>采用扫描config/mod/*.mod的方式进行注册路由</p>
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public void configRoute(Routes me) {
		Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forPackage("")).filterInputsBy(new FilterBuilder().include(".+\\.controller\\.[^\\.]+\\.class")));
		Set<Class<?>> controllers = reflections.getTypesAnnotatedWith(Controller.class);
		for(Class ctrl : controllers){
			Controller c = (Controller) ctrl.getAnnotation(Controller.class);
			if(StrUtil.isBlank(c.viewPath())){
				me.add(c.uri(), ctrl);
			}else{
				me.add(c.uri(), ctrl,c.viewPath());
			}
		}
	}

	@Override
	public void configEngine(Engine me) {
		// TODO Auto-generated method stub
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public void configPlugin(Plugins me) {
		// TODO Auto-generated method stub
		/**
		 * 数据库插件
		 */
		Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forPackage("/")).setScanners(new ResourcesScanner()));
		Set<String> _sql = reflections.getResources(Pattern.compile(".*\\.stl"));
		Setting setting = new Setting("config/jdbc.txt");
		boolean isFirst = true;
		/* 多数据源的支持，根据jdbc.txt配置文件中的setting设置方式 */
		Map<String,DruidPlugin> dps = new HashMap<String,DruidPlugin>();
		for(int i=0,ln=setting.getGroups().size();i<ln;i++){
		//for(String g : setting.getGroups()){
			String g = setting.getGroups().get(i);
			if(dps.get(g)==null){
				dps.put(g, new DruidPlugin(setting.getByGroup("jdbcUrl", g), setting.getByGroup("user", g), setting.getByGroup("password", g)));
			}
			me.add(dps.get(g));
			ActiveRecordPlugin arp = new ActiveRecordPlugin(g,dps.get(g));
			arp.setBaseSqlTemplatePath(PathKit.getRootClassPath());
			arp.setDevMode(config.getBool("dev_mode", "common", false));
			arp.setShowSql(config.getBool("dev_mode", "common", false));
			arp.getEngine().addSharedMethod(new StrKit());
			
			
			/* 获得sqltemplate文件 */
			if(_sql!=null){
				for(String sql : _sql){
					arp.addSqlTemplate(sql);
				}
			}
			/* 添加模型 */
			Reflections _reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forPackage("")).filterInputsBy(new FilterBuilder().include(".+\\.model\\.[^\\.]+\\.class")));
			//Reflections _reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forPackage("/")).filterInputsBy(new FilterBuilder().include(".*\\.model\\.class")));
			Set<Class<?>> models = _reflections.getTypesAnnotatedWith(Model.class);
			if(models!=null){
				for(Class _m : models){
					Model m = (Model) _m.getAnnotation(Model.class);
					/* 如果模型数据源为空，就要判断当前数据源是否为第一个 */
					if((g.equals(m.ds())||(StrUtil.isBlank(m.ds()) && isFirst))){
						if(StrUtil.isBlank(m.key())){
							arp.addMapping(m.table(), _m);
						}else{
							arp.addMapping(m.table(),m.key(),_m);
						}
					}
				}
			}
			me.add(arp);
			isFirst = false;
		}
	}

	@Override
	public void configInterceptor(Interceptors me) {
		// TODO Auto-generated method stub
		me.add(new ParameterValidatorInterceptor());
	}

	@Override
	public void configHandler(Handlers me) {
		// TODO Auto-generated method stub
		me.add(new ParameterFilterHandler(config.getSetting("cn.modfun.web.core.hanlder.ParameterFilterHandler")));
	}
	
	
	public static void main(String[] args) {
		// /^\.\/routes(.*)\/route\.js$/
		Pattern pattern = Pattern.compile(".+\\.controller\\.[^\\.]+\\.class");
		Matcher matcher = pattern.matcher("a.b.c.controller.aaa.class");
		boolean matches = matcher.matches();// true
		System.out.println(matches);

	}
}
